from django.shortcuts import render, get_object_or_404, redirect
from django.http import HttpRequest, HttpResponse
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
from .models import BookInstance, Author, Book
from django.views import generic
from django.contrib.auth.decorators import permission_required, login_required
from django import forms
from django.urls import reverse_lazy
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.db.models import Q, Count
from django.contrib import messages

def index(request: HttpRequest) -> HttpResponse:
    num_visits = request.session.get('num_visits', 0)
    request.session['num_visits'] = num_visits + 1
    # 统计
    num_books = Book.objects.count()
    num_authors = Author.objects.count()
    num_available = BookInstance.objects.filter(status='a').count()
    # 热门图书（按借出次数排序，取前3）
    hot_books = Book.objects.annotate(borrowed_count=Count('bookinstance', filter=Q(bookinstance__status='o'))).order_by('-borrowed_count')[:3]
    # 知名作者（按图书数量排序，取前2）
    famous_authors = Author.objects.annotate(book_count=Count('book')).order_by('-book_count')[:2]
    context = {
        'num_visits': num_visits + 1,
        'num_books': num_books,
        'num_authors': num_authors,
        'num_available': num_available,
        'hot_books': hot_books,
        'famous_authors': famous_authors,
    }
    return render(request, 'index.html', context)

class LoanedBooksByUserListView(LoginRequiredMixin, generic.ListView):
    model = BookInstance
    template_name = 'my_borrowed_books.html'
    paginate_by = 10

    def get_queryset(self):
        return BookInstance.objects.filter(borrower=self.request.user, status='o').order_by('due_back')

class RenewBookForm(forms.Form):
    renewal_date = forms.DateField(
        help_text="请输入一个介于今天和4周内的日期。",
        widget=forms.TextInput(attrs={'type': 'date'})
    )

@permission_required('catalog.can_mark_returned', raise_exception=True)
def renew_book_librarian(request, pk):
    book_instance = get_object_or_404(BookInstance, pk=pk)
    if request.method == 'POST':
        form = RenewBookForm(request.POST)
        if form.is_valid():
            book_instance.due_back = form.cleaned_data['renewal_date']
            book_instance.save()
            return redirect('my-borrowed')
    else:
        proposed_renewal_date = book_instance.due_back
        form = RenewBookForm(initial={'renewal_date': proposed_renewal_date})
    return render(request, 'book_renew_librarian.html', {'form': form, 'book_instance': book_instance})

class AuthorCreate(CreateView):
    model = Author
    fields = '__all__'
    template_name = 'author_form.html'
    success_url = reverse_lazy('index')

class AuthorUpdate(UpdateView):
    model = Author
    fields = '__all__'
    template_name = 'author_form.html'
    success_url = reverse_lazy('index')

class AuthorDelete(DeleteView):
    model = Author
    template_name = 'author_confirm_delete.html'
    success_url = reverse_lazy('index')

class AuthorListView(generic.ListView):
    model = Author
    template_name = 'author_list.html'
    paginate_by = 10

class AuthorDetailView(generic.DetailView):
    model = Author
    template_name = 'author_detail.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['books'] = Book.objects.filter(author=self.object)
        return context

class AllBorrowedBooksListView(PermissionRequiredMixin, generic.ListView):
    model = BookInstance
    permission_required = 'catalog.can_mark_returned'
    template_name = 'all_borrowed_books.html'
    paginate_by = 10

    def get_queryset(self):
        return BookInstance.objects.filter(status='o').order_by('due_back')

def book_search(request):
    query = request.GET.get('q', '').strip()
    results = []
    if query:
        results = Book.objects.filter(
            Q(title__icontains=query) | Q(author__first_name__icontains=query) | Q(author__last_name__icontains=query)
        )
    context = {
        'query': query,
        'results': results,
    }
    return render(request, 'book_search_results.html', context)

def book_detail(request, pk):
    book = get_object_or_404(Book, pk=pk)
    # 获取所有实例
    instances = BookInstance.objects.filter(book=book)
    user = request.user
    can_borrow = user.is_authenticated and instances.filter(status='a').exists()
    user_borrowed = user.is_authenticated and instances.filter(borrower=user, status='o').exists()
    if request.method == 'POST' and user.is_authenticated:
        action = request.POST.get('action')
        if action == 'borrow' and can_borrow:
            instance = instances.filter(status='a').first()
            instance.status = 'o'
            instance.borrower = user
            instance.save()
            messages.success(request, '借阅成功！')
            return redirect('book-detail', pk=book.pk)
        elif action == 'return' and user_borrowed:
            instance = instances.filter(borrower=user, status='o').first()
            instance.status = 'a'
            instance.borrower = None
            instance.save()
            messages.success(request, '归还成功！')
            return redirect('book-detail', pk=book.pk)
    context = {
        'book': book,
        'instances': instances,
        'can_borrow': can_borrow,
        'user_borrowed': user_borrowed,
    }
    return render(request, 'book_detail.html', context)

class LoanHistoryView(LoginRequiredMixin, generic.ListView):
    model = BookInstance
    template_name = 'my_loan_history.html'
    paginate_by = 10
    def get_queryset(self):
        return BookInstance.objects.filter(borrower=self.request.user).order_by('-due_back')
